from math import sqrt
import math
import colorsys

RGB_SCALE = 255
CMYK_SCALE = 100


def rgb_to_cmyk(r, g, b):
    if (r, g, b) == (0, 0, 0):
        # black
        return 0, 0, 0, CMYK_SCALE

    # rgb [0,255] -> cmy [0,1]
    c = 1 - r / RGB_SCALE
    m = 1 - g / RGB_SCALE
    y = 1 - b / RGB_SCALE

    # extract out k [0, 1]
    min_cmy = min(c, m, y)
    c = (c - min_cmy) / (1 - min_cmy)
    m = (m - min_cmy) / (1 - min_cmy)
    y = (y - min_cmy) / (1 - min_cmy)
    k = min_cmy

    # rescale to the range [0,CMYK_SCALE]
    return c * CMYK_SCALE, m * CMYK_SCALE, y * CMYK_SCALE, k * CMYK_SCALE

def color_diff(rgb1, rgb2, use="rgb:RGB", use_func="sqrt"):
    r1, g1, b1 = rgb1
    r2, g2, b2 = rgb2
    k1 = 0
    k2 = 0
    if use.startswith("hsv:"):
        (r1, g1, b1) = rgb2hsv(r1 , g1 , b1 )
        (r2, g2, b2) = rgb2hsv(r2 , g2 , b2 )
    elif use.startswith('hls'):
        (r1, g1, b1) = colorsys.rgb_to_hls(r1 / 255, g1 / 255, b1 / 255)
        (r2, g2, b2) = colorsys.rgb_to_hls(r2 / 255, g2 / 255, b2 / 255)
    elif use.startswith('yiq'):
        (r1, g1, b1) = colorsys.rgb_to_yiq(r1 / 255, g1 / 255, b1 / 255)
        (r2, g2, b2) = colorsys.rgb_to_yiq(r2 / 255, g2 / 255, b2 / 255)
    elif use.startswith("cmyk"):
        (r1, g1, b1,k1) = rgb_to_cmyk(r1 , g1 , b1 )
        (r2, g2, b2,k2) = rgb_to_cmyk(r2 , g2 , b2 )

    use_type,user_value = use.split(":")

    cac_value_a = []
    cac_value_b = []
    # 计算每个颜色分量的差值
    if "R" in use or "H" in use or "Y" in use or "c" in use:
        r_diff = r1 - r2
        cac_value_a.append(r1)
        cac_value_b.append(r2)
    else:
        r_diff = 0

    if "G" in use or (use_type == "hsv" and "S" in use) or "L" in use or "I" in use or 'm' in use:
        g_diff = g1 - g2
        cac_value_a.append(g1)
        cac_value_b.append(g2)
    else:
        g_diff = 0

    if "B" in use or "V" in use or (use_type == "hls" and "S" in use) or "Q" in use or 'y' in use:
        b_diff = b1 - b2
        cac_value_a.append(b1)
        cac_value_b.append(b2)
    else:
        b_diff = 0

    if 'k' in use:
        k_diff = k1 - k2
        cac_value_a.append(k1)
        cac_value_b.append(k2)
    else:
        k_diff = 0

    # 对差值平方和开根号得到距离
    if use_func == 'sqrt':
        distance = sqrt(r_diff ** 2 + g_diff ** 2 + b_diff ** 2 + k_diff **2)
    elif use_func == 'cos':
        distance = -cosine_similarity(cac_value_a, cac_value_b)
        if len(cac_value_a) == 1:
            distance = distance / (abs(cac_value_a[0] - cac_value_b[0]) + 0.00001)

    return distance


def cosine_similarity(vec1, vec2):
    dot_product = sum(a * b for a, b in zip(vec1, vec2))
    magnitude_vec1 = math.sqrt(sum(a * a for a in vec1))
    magnitude_vec2 = math.sqrt(sum(b * b for b in vec2))
    if magnitude_vec1 == 0 or magnitude_vec2 == 0:
        return 0
    return dot_product / (magnitude_vec1 * magnitude_vec2)


def conver_str2rgb(color_str):
    # 将16进制字符串转换为整数
    red = int(color_str[0:2], 16)
    green = int(color_str[2:4], 16)
    blue = int(color_str[4:6], 16)
    return (red, green, blue)


def cmyk_to_rgb(c, m, y, k):
    """
    Convert CMYK color to RGB color.
    """
    # 将 CMYK 值转换为 0 到 1 之间的值
    c = c / 100
    m = m / 100
    y = y / 100
    k = k / 100

    # 通过以下公式将 CMYK 转换为 RGB
    r = 1 - c - k
    g = 1 - m - k
    b = 1 - y - k

    # 将 RGB 值映射到 0 到 255 之间，以便在 RGB 颜色空间中使用
    r = int(r * 255)
    g = int(g * 255)
    b = int(b * 255)

    return (r, g, b)


def rgb_to_hex(rgb):
    return "#{:02x}{:02x}{:02x}".format(rgb[0], rgb[1], rgb[2])

def rgb2hsv(r, g, b):
    '''
    RGB转HSV
    r,g,b在(0-255)
    '''
    r, g, b = r/255.0, g/255.0, b/255.0
    mx, mn = max(r, g, b), min(r, g, b)
    m = mx-mn
    if mx == mn:
        h = 0
    elif mx == r:
        if g >= b:
            h = ((g-b)/m)*60
        else:
            h = ((g-b)/m)*60 + 360
    elif mx == g:
        h = ((b-r)/m)*60 + 120
    elif mx == b:
        h = ((r-g)/m)*60 + 240
    if mx == 0:
        s = 0
    else:
        s = m/mx
    v = mx
    return round(h), round(s*100), round(v*100)

if __name__ == '__main__':
    print(rgb2hsv(140, 140, 140))
